#ifndef CPLANE3D_H_
#define CPLANE3D_H_

#include "cline3d.h"
#include "../exception/cintersectnotexistexception.h"

/**
 * CPlane3D - plane in 3D space using implicit representation
 * @author Michal Rost
 * @date 20.06.2007
 */
template <typename T>
class CPlane3D : public CObject {
public:
  CPlane3D();
  CPlane3D(const CPlane3D<T> &plane);
  CPlane3D(const CVector3D<T> &normal, T originDist);
  CPlane3D(T normalX, T normalY, T normalZ, T originDist);
  CPlane3D(const CVector3D<T> &p1, const CVector3D<T> &p2,
           const CVector3D<T> &p3);
  bool operator == (const CPlane3D<T> &plane) const;
  bool operator != (const CPlane3D<T> &plane) const;
  void set(const CVector3D<T> &normal, T originDist);
  bool isPointOnPlane(const CVector3D<T> &p);
  bool isIntersecting(const CPlane3D<T> &plane);
  bool isIntersecting(const CLine3D<T> &l);
  bool isIntersecting(const CVector3D<T> &p1, const CVector3D<T> &p2);
  bool isParallel(const CPlane3D<T> &plane);
  bool isParallel(const CLine3D<T> &l);
  CVector3D<T> findIntersection(const CLine3D<T> &l);
  CVector3D<T> getNormal() const;
  T getOriginDist() const;
  T pointDist(const CVector3D<T> &p);
  T planeDist(const CPlane3D<T> &plane);
  T lineDist(const CLine3D<T> &l);
  static string getClassName() {
    static const string CLASS_NAME = "CPlane3D";
    return CLASS_NAME;
  }
protected:
  CVector3D<T> normal;
  T originDist;
  void copyFrom(const CPlane3D<T> &plane);
  void init(CVector3D<T> normal, T dist);
  static const unsigned int VECTOR_SPACE_3D = 3;
};

#endif
